﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Common.Logging;
 
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace Out.TaskRunner.RmqWorkers
{
    public class OrderPickupingWorker : IWorker
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(OrderPickupingWorker));

        public void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }

            using (var consumer = new OrderPickupingConsumer())
            {
                consumer.Subscribe((id, count, dt, msg, channel) =>
                {
                    if (msg.OrderType == OrderType.挂号订单)
                    {
                        return ProcessRegOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.门诊缴费订单)
                    {
                        return ProcessBillOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.扫码支付订单)
                    {
                        return ProcessSCBillOrder(msg.OrderId, channel);
                    }


                    return new ConsumedResult { Ack = true };
                });

                while (true)
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(500);
                }
            }
        }

        private ConsumedResult ProcessRegOrder(int orderId, WrapperChannel channel)
        {
            OrderSummary order;
            using (var ctx = new HzfyWeiXinEntities())
            {
                order = ctx.ApptOrder.Where(x => x.Id == orderId)
                    .Select(x => new OrderSummary
                    {
                        Id = x.Id,
                        OrderType = x.OrderType,
                        CardNo = x.CardNo,
                        CardType = x.CardType,
                        OrderStatus = x.OrderStatus,
                        OrderNo = x.OrderNo,
                        SumFee = x.SumFee,
                        WxTransactionId = x.WxTransactionId,
                        PayTime = x.PayTime,
                        WxUserId = x.WxUserId,
                        DeptId = x.DeptId,
                        RegDate = x.RegDate,
                        TimeSlice = x.TimeSlice,
                        TreatFee = x.TreatFee,
                        Fee = x.Fee,
                        RegNo = x.RegNo,
                        BranchNo = x.BranchNo,
                        StartTime = x.StartTime,
                        EndTime = x.EndTime,
                        OtherFee = x.OtherFee,
                        DoctorId = x.DoctorId,
                        DeptName = x.DeptName,
                        DoctorName = x.DoctorName
                    }).FirstOrDefault();
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
            }

            // 取号中
            //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号中.ToInt32();
            //ctx.SaveChanges();
            using (var _ctx = new HzfyWeiXinEntities())
            {
                SqlParameter[] para =
                {
                                new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号中.ToInt32()),
                                new SqlParameter("@OrderId", order.Id),
                            };
                _ctx.Database.ExecuteSqlCommand(
                    "Update ApptOrder set OrderStatus= @OrderStatus where Id=@OrderId", para);
            }

            var directRegRequest = new ExeAppointRequest();
            directRegRequest.OrderId = order.OrderNo;
            directRegRequest.TransactionId = order.WxTransactionId;
            directRegRequest.ScheduleItemCode = order.BranchNo;
            directRegRequest.CardNo = order.CardNo;
            directRegRequest.CardType = order.CardType;
            directRegRequest.PayFee = order.SumFee.GetValueOrDefault().ToString();
            directRegRequest.QueueNo = order.RegNo ?? "";

            ExeAppointResponse directRegResponse;

            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/ExeAppoint", directRegRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                directRegResponse = responseMsg.Content.ReadAsAsync<ExeAppointResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内直接取号Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                // RMQ 执行取号结果查询
                var pickupingChkProducer = new OrderPickupingChkProducer();
                pickupingChkProducer.Publish(new OrderPickupingChkMsg
                {
                    OrderType = Rmq.Center.OrderType.挂号订单,
                    OrderId = order.Id
                }, 5 * 60 * 1000);

                return new ConsumedResult
                {
                    Ack = true
                };
            }

            if (directRegResponse.ResultCode != "0")
            {
                // 取号失败
                //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号失败.ToInt32();
                //order.Remark = directRegResponse.ResultDesc;
                //ctx.SaveChanges();
                using (var _ctx = new HzfyWeiXinEntities())
                {
                    SqlParameter[] para =
                    {
                                new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号失败.ToInt32()),
                                new SqlParameter("@Remark", directRegResponse.ResultDesc),
                                 //new SqlParameter("@VisitNo", directRegResponse.AdmNo),
                                new SqlParameter("@OrderId", order.Id),
                            };
                    _ctx.Database.ExecuteSqlCommand(
                        "Update ApptOrder set OrderStatus= @OrderStatus,Remark=@Remark where Id=@OrderId", para);
                }

                // RMQ 发送用户挂号失败通知
                var msgProducer = new UserMessageProducer();
                msgProducer.Publish(new UserMessageMsg
                {
                    Type = UserMessageType.挂号失败通知,
                    OrderId = order.Id
                });

                // RMQ 执行取消锁号操作
                var unlockingProducer = new OrderUnlockingProducer();
                unlockingProducer.Publish(new OrderUnlockingMsg
                {
                    OrderType = OrderType.挂号订单,
                    OrderId = orderId
                });
                // RMQ 执行退费操作
                if (order.SumFee > 0)
                {
                    var refundingProducer = new OrderRefundingPickupFailedProducer();
                    refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                    {
                        OrderType = OrderType.挂号订单,
                        OrderId = order.Id
                    });
                }
            }
            else
            {
                // 取号成功
                //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号成功.ToInt32();
                //order.RegNo = directRegResponse.RegNo;
                //order.SuggestBeginTime = directRegResponse.BeginTime;
                //order.SuggestEndTime = directRegResponse.EndTime;
                //order.Location = directRegResponse.Address;
                //order.VisitNo = directRegResponse.VisitNo;

                //order.FetchTime = DateTime.Now;
                //ctx.SaveChanges();
                using (var ctx = new HzfyWeiXinEntities())
                {
                    var para = new SqlParameter[]
                    {
                            new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号成功.ToInt32()),
                            new SqlParameter("@RegNo", directRegResponse.SeqCode),
                            new SqlParameter("@Location", directRegResponse.AdmitAddress),
                            new SqlParameter("@VisitNo", directRegResponse.AdmNo),
                            new SqlParameter("@FetchTime", DateTime.Now),
                            new SqlParameter("@OrderId", order.Id)
                    };
                    ctx.Database.ExecuteSqlCommand("Update ApptOrder set OrderStatus= @OrderStatus," +
                                                   "RegNo = @RegNo,Location=@Location,VisitNo=@VisitNo," +
                                                   "FetchTime=@FetchTime where Id=@OrderId", para);
                }
                // RMQ 发送用户挂号成功通知
                var messageProducer = new UserMessageProducer();
                messageProducer.Publish(new UserMessageMsg
                {
                    Type = UserMessageType.挂号成功通知,
                    OrderId = order.Id
                });

                // RMQ 发送发货通知
                if (order.SumFee > 0)
                {
                    using (var ctx = new HzfyWeiXinEntities())
                    {
                        var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                        if (wxuser != null)
                        {
                            //TenpayV2Helper.DoDeliverNotify(wxuser.OpenId, order.WxTransactionId,
                            //"AP" + order.OrderNo, "1", "");
                            WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                                "AP" + order.OrderNo,
                                ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                    .ToString(), "1", "");
                        }
                    }
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessBillOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new HzfyWeiXinEntities())
            {
                var order = ctx.BillOrder.FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                // 缴费中
                order.OrderStatus = BillOrderExtensions.OrderStatus.缴费中.ToInt32();
                ctx.SaveChanges();


                // 自费缴费
                var personPayRequest = new ExePrescriptionPayRequest();
                //执行缴费操作
                personPayRequest.InsuTypeDR = "1";
                personPayRequest.OrderId = order.OrderNo;
                personPayRequest.AdmInfo = order.ClinicNo;
                personPayRequest.PatientID = order.CardNo;
                personPayRequest.SumFee = ("0" + order.PrescMoney).ToDecimalOrDefault().ToString("F2");
                personPayRequest.TransNo = order.WxTransactionId;
                personPayRequest.TransTime = order.PayTime.ToString();

                ExePrescriptionPayResponse personPayResponse;
                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisWs/ExePrescriptionPay", personPayRequest).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    personPayResponse = responseMsg.Content.ReadAsAsync<ExePrescriptionPayResponse>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内缴费Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                    // RMQ 执行缴费状态结果查询
                    var pickupingChkProducer = new OrderPickupingChkProducer();
                    pickupingChkProducer.Publish(new OrderPickupingChkMsg
                    {
                        OrderType = Rmq.Center.OrderType.门诊缴费订单,
                        OrderId = order.Id
                    }, 5 * 60 * 1000);

                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                if (personPayResponse.ResultCode != "0")
                {
                    // RMQ 执行缴费状态结果查询
                    var pickupingChkProducer = new OrderPickupingChkProducer();
                    pickupingChkProducer.Publish(new OrderPickupingChkMsg
                    {
                        OrderType = Rmq.Center.OrderType.门诊缴费订单,
                        OrderId = order.Id
                    }, 5 * 60 * 1000);

                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
                else
                {
                    // 缴费成功
                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();

                    //foreach (var disWin in personPayResponse.InvoiceList)
                    //{
                    //    var newBillOrderDisWin = new BillOrderDisWin
                    //    {
                    //        BillOrderId = order.Id,
                    //        DisWin = disWin.DisWin,
                    //        DisWinAdd = disWin.DisWinAdd,
                    //       // RcptNo = disWin.RcptNo,
                    //        VisitNo = disWin.VisitNo
                    //    };
                    //    ctx.BillOrderDisWin.Add(newBillOrderDisWin);
                    //}
                    foreach (var disWin in personPayResponse.InvoiceList)
                    {
                        order.RealRcptNo = disWin.InvoiceNO;
                    }
                    order.Remark = personPayResponse.ResultDesc;

                    order.FetchTime = DateTime.Now;
                    ctx.SaveChanges();

                    // RMQ 发起缴费成功通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        OrderId = order.Id,
                        Type = UserMessageType.缴费成功通知
                    });
                    var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                    if (wxuser != null)
                    {
                        // RMQ 发送发货通知
                        //TenpayV2Helper.DoDeliverNotify(wxuser.OpenId, order.WxTransactionId,
                        //    "BL" + order.OrderNo, "1", "");
                        WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                       "BL" + order.OrderNo, ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                        .ToString(), "1", "");
                    }
                }
            }
           

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessSCBillOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new HzfyWeiXinEntities())
            {
                var order = ctx.BillOrder.FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                // 缴费中
                order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();
                ctx.SaveChanges();

                #region 执行缴费操作
                //var personPayRequest = new ExePrescriptionPayRequest();
                ////执行缴费操作
                //personPayRequest.InsuTypeDR = "1";
                //personPayRequest.OrderId = order.OrderNo;
                //personPayRequest.AdmInfo = order.ClinicNo;
                //personPayRequest.PatientID = order.CardNo;
                //personPayRequest.SumFee = ("0" + order.PrescMoney).ToDecimalOrDefault().ToString("F2");
                //personPayRequest.TransNo = order.WxTransactionId;
                //personPayRequest.TransTime = order.PayTime.ToString();

                //ExePrescriptionPayResponse personPayResponse;
                //try
                //{
                //    var httpClient = InHttpClient.GetClient();
                //    var responseMsg = httpClient.PostAsJsonAsync("HisWs/ExePrescriptionPay", personPayRequest).Result;
                //    responseMsg.EnsureSuccessStatusCode();
                //    personPayResponse = responseMsg.Content.ReadAsAsync<ExePrescriptionPayResponse>().Result;
                //}
                //catch (Exception ex)
                //{
                //    Logger.ErrorFormat("调用院内缴费Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                //    // RMQ 执行缴费状态结果查询
                //    var pickupingChkProducer = new OrderPickupingChkProducer();
                //    pickupingChkProducer.Publish(new OrderPickupingChkMsg
                //    {
                //        OrderType = Rmq.Center.OrderType.门诊缴费订单,
                //        OrderId = order.Id
                //    }, 5 * 60 * 1000);

                //    return new ConsumedResult
                //    {
                //        Ack = true
                //    };
                //}

                //if (personPayResponse.ResultCode != "0")
                //{
                //    // RMQ 执行缴费状态结果查询
                //    var pickupingChkProducer = new OrderPickupingChkProducer();
                //    pickupingChkProducer.Publish(new OrderPickupingChkMsg
                //    {
                //        OrderType = Rmq.Center.OrderType.门诊缴费订单,
                //        OrderId = order.Id
                //    }, 5 * 60 * 1000);

                //    return new ConsumedResult
                //    {
                //        Ack = true
                //    };
                //}
                //else
                //{
                //    // 缴费成功
                //    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();

                //    //foreach (var disWin in personPayResponse.InvoiceList)
                //    //{
                //    //    var newBillOrderDisWin = new BillOrderDisWin
                //    //    {
                //    //        BillOrderId = order.Id,
                //    //        DisWin = disWin.DisWin,
                //    //        DisWinAdd = disWin.DisWinAdd,
                //    //       // RcptNo = disWin.RcptNo,
                //    //        VisitNo = disWin.VisitNo
                //    //    };
                //    //    ctx.BillOrderDisWin.Add(newBillOrderDisWin);
                //    //}
                //    foreach (var disWin in personPayResponse.InvoiceList)
                //    {
                //        order.RealRcptNo = disWin.InvoiceNO;
                //    }
                //    order.Remark = personPayResponse.ResultDesc;
                //    order.FetchTime = DateTime.Now;
                //    ctx.SaveChanges();

                //    // RMQ 发起缴费成功通知
                //    var messageProducer = new UserMessageProducer();
                //    messageProducer.Publish(new UserMessageMsg
                //    {
                //        OrderId = order.Id,
                //        Type = UserMessageType.缴费成功通知
                //    });
                //    var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                //    if (wxuser != null)
                //    {
                //        // RMQ 发送发货通知
                //        //TenpayV2Helper.DoDeliverNotify(wxuser.OpenId, order.WxTransactionId,
                //        //    "BL" + order.OrderNo, "1", "");
                //        WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                //       "BL" + order.OrderNo, ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                //                        .ToString(), "1", "");
                //    }
                //}
                #endregion
            }


            return new ConsumedResult
            {
                Ack = true
            };
        }

        public class OrderSummary
        {
            public string OrderNo { get; set; }
            public string OrderType { get; set; }
            public int Id { get; set; }
            public decimal? SumFee { get; set; }
            public long? WxUserId { get; set; }
            public string WxTransactionId { get; set; }
            public DateTime? PayTime { get; set; }
            public string CardNo { get; set; }
            public int OrderStatus { get; set; }
            public string DeptName { get; set; }
            public string DoctorName { get; set; }
            public string DeptId { get; set; }
            public string RegDate { get; set; }
            public string TimeSlice { get; set; }
            public string BranchNo { get; set; }
            public decimal? TreatFee { get; set; }
            public decimal? Fee { get; set; }
            public string RegNo { get; set; }
            public string StartTime { get; set; }
            public string EndTime { get; set; }
            public decimal? OtherFee { get; set; }
            public string DoctorId { get; set; }
            public string CardType { get; internal set; }
        }
    }
}